/*
 * @Author: LiZhiJian
 * @Description: 
 * @Date: 2025-10-26 14:54:13
 * @LastEditTime: 2025-10-26 16:27:03
 * @Email: LiZhiJian8552@163.com
 */

#include "usart1.h"
#include "delay.h"

#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>

// 定义串口接收的数据 1表示有数据
uint8_t USART1_RxData;
// 定义串口接收的标记位
uint8_t USART1_RxFlag;

// 初始化USART1
void USART1_Init(){
    // 开启时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);

    // 引脚初始化
    GPIO_InitTypeDef GPIO_InitStruct={0};
    GPIO_InitStruct.GPIO_Pin=GPIO_Pin_9;
    GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF_PP;
    GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
    GPIO_Init(GPIOA,&GPIO_InitStruct);

    GPIO_InitStruct.GPIO_Pin=GPIO_Pin_10;
    GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IPU;
    GPIO_Init(GPIOA,&GPIO_InitStruct);

    // 初始化USART
    USART_InitTypeDef USART_InitStruct={0};
    USART_InitStruct.USART_BaudRate=115200;
    USART_InitStruct.USART_HardwareFlowControl=USART_HardwareFlowControl_None;
    USART_InitStruct.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;
    USART_InitStruct.USART_Parity=USART_Parity_No;
    USART_InitStruct.USART_StopBits=USART_StopBits_1;
    USART_InitStruct.USART_WordLength=USART_WordLength_8b;

    USART_Init(USART1,&USART_InitStruct);
    // 使能USART1
    USART_Cmd(USART1,ENABLE);


    // 中断输出配置
    // 开启USART1数据到达时中断
    USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);
    // 配置NVIC中断分组
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

    // 配置NVIC
    NVIC_InitTypeDef NVIC_InitStruct={0};
    NVIC_InitStruct.NVIC_IRQChannel=USART1_IRQn;
    NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;
    NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=1;
    NVIC_InitStruct.NVIC_IRQChannelSubPriority=1;
    NVIC_Init(&NVIC_InitStruct);

}


void USART1_SendByte(uint8_t Byte){
    USART_SendData(USART1,Byte);
    // 等待数据发送完成
    while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);
}

void USART1_SendArray(uint8_t *Array, uint16_t Length){
    for(uint16_t i=0;i<Length;i++){
        USART1_SendByte(Array[i]);
    }
}

void USART1_SendString(char *String){
    for(uint16_t i=0;String[i]!='\0';i++){
        USART1_SendByte(String[i]);
    }
}

/**
  * 函    数：次方函数（内部使用）
  * 返 回 值：返回值等于X的Y次方
  */
uint32_t Serial_Pow(uint32_t X,uint32_t Y){
    uint32_t result=1;
    while(Y--){
        result*=X;
    }
    return result;
}

/**
  * 函    数：串口发送数字
  * 参    数：Number 要发送的数字，范围：0~4294967295
  * 参    数：Length 要发送数字的长度，范围：0~10
  * 返 回 值：无
  */
void USART1_SendNumber(uint32_t Number, uint8_t Length){
    for(uint8_t i=0;i<Length;i++){
        USART1_SendByte(Number/Serial_Pow(10,Length-i-1)%10+'0');
    }
}

/**
  * 函    数：使用printf需要重定向的底层函数
  * 参    数：保持原始格式即可，无需变动
  * 返 回 值：保持原始格式即可，无需变动
  */
int USART1_fputc(int ch, FILE *f){
	USART1_SendByte(ch);			//将printf的底层重定向到自己的发送字节函数
	return ch;
}

/**
  * 函    数：自己封装的prinf函数
  * 参    数：format 格式化字符串
  * 参    数：... 可变的参数列表
  * 返 回 值：无
  */
void USART1_Printf(char *format, ...){
	char String[100];				//定义字符数组
	va_list arg;					//定义可变参数列表数据类型的变量arg
	va_start(arg, format);			//从format开始，接收参数列表到arg变量
	vsprintf(String, format, arg);	//使用vsprintf打印格式化字符串和参数列表到字符数组中
	va_end(arg);					//结束变量arg
	USART1_SendString(String);		//串口发送字符数组（字符串）
}


/**
  * 函    数：获取串口接收标志位
  * 参    数：无
  * 返 回 值：串口接收标志位，范围：0~1，接收到数据后，标志位置1，读取后标志位自动清零
  */
uint8_t USART1_GetRxFlag(void){
    if(USART1_RxFlag==1){
        USART1_RxFlag=0;
        return 1;
    }
    return 0;
}

/**
  * 函    数：获取串口接收的数据
  * 参    数：无
  * 返 回 值：接收的数据，范围：0~255
  */
uint8_t USART1_GetRxData(void){
	return USART1_RxData;			//返回接收的数据变量
}

void USART1_IRQHandler(void){
    // 有数据到达
    if(USART_GetITStatus(USART1,USART_IT_RXNE)==SET){
        USART1_RxData=USART_ReceiveData(USART1);
        USART1_RxFlag=1;
        // 清除标记位
        USART_ClearITPendingBit(USART1,USART_IT_RXNE);
    }
}
